package com.wzl.myviewgroup.SlideMenu;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller;
import android.widget.TextView;

import com.wzl.myviewgroup.R;

public class SlideMenuViewGroup extends ViewGroup implements View.OnClickListener {
    private static final String TAG = "SlideMenuViewGroup";
    private View mEditView;
    private View mContentView;
    private OnEditClickListener mEditClickListener=null;
    private TextView mReadTv;
    private TextView mTopTv;
    private TextView mDelTv;
    private float mDownX;
    private float mDowny;
//用于处理屏幕平滑滚动的工具类。它并不是直接关联到视图（View）的滚动，而是提供了一个基于时间的平滑滚动算法。
    //Scroller 通常与 View 的 computeScroll() 方法一起使用
    private Scroller mScroller;
    private boolean isOpen = false;
    private Directions mCurrentDirect = Directions.NONE;
    private float mInterceptDownX;

    enum Directions {
        LEFT, RIGHT,NONE;
    }
    //走完mEditView5/6宽度所需要的时间
    private int mMaxDuration=800;
    private int mMinDuration=300;

    public SlideMenuViewGroup(Context context) {
        this(context,null);
    }

    public SlideMenuViewGroup(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public SlideMenuViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //获取自定义属性
        @SuppressLint("Recycle") TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideMenuViewGroup);
        int function = a.getInt(R.styleable.SlideMenuViewGroup_function, 0x30);
//        Log.d(TAG,"function ==> " + function);
        a.recycle();
        //获取不到子控件个数，因为使用包裹布局（XML中定义子控件），子控件个数为0
        //重载onFinishInflate()方法，在子控件被添加到ViewGroup中时调用
        /*int childCount = getChildCount();
        Log.d(TAG,"childCount ==> " + childCount);*/
        mScroller = new Scroller(context);
    }

   /* public SlideMenuViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }*/

    //重载onTouchEvent()方法，处理触摸事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mDownX = event.getX();
                mDowny = event.getY();
//                Log.d(TAG,"onTouchEvent  ACTION_DOWN x ==> " + mDownX);
//                Log.d(TAG,"onTouchEvent  ACTION_DOWN y ==> " + mDowny);

//                Log.d(TAG,"onTouchEvent  ACTION_DOWN");
                break;
            case MotionEvent.ACTION_MOVE:
                float move_x = event.getX();//获取当前触摸点的X坐标
                float move_y = event.getY();
//                Log.d(TAG,"onTouchEvent  ACTION_MOVE x ==> " + move_x);
//                Log.d(TAG,"onTouchEvent  ACTION_MOVE y ==> " + move_y);

                int scrollX = getScrollX();//获取当前ViewGroup的滚动X左边界的位置,右移负数,左移正数
                int scrollY = getScrollY();//获取当前ViewGroup的滚动Y,即ViewGroup中第一个View的Y坐标
//                Log.d(TAG,"onTouchEvent  ACTION_MOVE scrollX ==> " + scrollX);
//                Log.d(TAG,"onTouchEvent  ACTION_MOVE scrollY ==> " + scrollY);

                //移动的差值(距离)
                int dx = (int) (move_x - mDownX);
                if (dx>0) {//向右方向
                    mCurrentDirect = Directions.RIGHT;
                }else {
                    mCurrentDirect = Directions.LEFT;
                }

//                Log.d(TAG,"onTouchEvent  ACTION_MOVE dx ==> " + dx);

                int resultScrollx = -dx+ scrollX;
//                Log.d(TAG,"onTouchEvent  ACTION_MOVE resultScrollx ==> " + resultScrollx);
                if (resultScrollx<=0) {
                    scrollTo(0,scrollY);
                }else if(resultScrollx>mEditView.getMeasuredWidth()){
                    scrollTo(mEditView.getMeasuredWidth(),scrollY);
                }else {
                    scrollBy(-dx, 0);//移动ViewGroup，向右移动dx,向左移动-dx
                }
//                mContentLeft += dx;
//                requestLayout();//重新布局,消耗资源。
                mDownX=move_x;
                mDowny=move_y;
//                Log.d(TAG,"onTouchEvent  ACTION_MOVE mDownX ==> " + mDownX);
//                Log.d(TAG,"onTouchEvent  ACTION_MOVE mDowny ==> " + mDowny);
//                Log.d(TAG,"onTouchEvent  ACTION_MOVE");
                break;
            case MotionEvent.ACTION_UP:
//                Log.d(TAG,"onTouchEvent  ACTION_UP");
                float upx = event.getX();
                float upy = event.getY();
                /*Log.d(TAG,"onTouchEvent  ACTION_UP upx ==> " + upx);
                Log.d(TAG,"onTouchEvent  ACTION_UP upy ==> " + upy);*/

                //处理释放以后，是显示还是收缩回去
                //两个关注点
                //1。是否已经打开
                //2。方向
//                Log.d(TAG,"onTouchEvent  ACTION_UP mCurrentDirect ==> " + mCurrentDirect);

                /*int hasBeenScrolled = getScrollX();
                if (hasBeenScrolled>=mEditView.getMeasuredWidth()/2) {//过了编辑框的一半就打开
                    //scrollTo(mEditView.getMeasuredWidth(),0);
                    //使用Scroller类，实现平滑滚动
                    //startScroll(int startX, int startY, int dx, int dy)
                    //startX,开始滚动的X坐标
                    //startY,开始滚动的Y坐标
                    //dx,滚动的X坐标
                    //dy,滚动的Y坐标
                    //duration,滚动的时间
                    //得到一个差值，由computeScroll重载方法实现重绘
                    mScroller.startScroll(hasBeenScrolled,0,mEditView.getMeasuredWidth()-hasBeenScrolled,0,1000);
                    isOpen = true;
                }else {
                //scrollTo(0,0);
                    mScroller.startScroll(hasBeenScrolled,0,-hasBeenScrolled,0,1000);
                    isOpen = false;
                }*/
                int hasBeenScrolled = getScrollX();
                int editViewWidth = mEditView.getMeasuredWidth();
                if (isOpen) {
                    if (mCurrentDirect==Directions.RIGHT) {
                        //向右滑动，判断滑动距离是否小于编辑框3/4，小于就关闭，否则打开
                        if (hasBeenScrolled<=editViewWidth*5/6) {
                            //关闭
                            close();
                        }else {
                            //打开
                            open();
                        }
                    }else if(mCurrentDirect==Directions.LEFT) {
                        open();
                    }
                }else {
                    //当前状态关闭
                    if (mCurrentDirect==Directions.LEFT) {
                        //向左滑动，判断滑动距离是否大于编辑框1/4，大于就打开，否则关闭
                        if (hasBeenScrolled>=editViewWidth/6) {
                            //打开
                            open();
                        }else {
                            //关闭
                            close();
                        }
                    }else if(mCurrentDirect==Directions.RIGHT){
                        close();
                    }
                }



                break;
        }

        //返回true，表示事件被处理
        //返回false，表示事件没有被处理
        return true;
//        return super.onTouchEvent(event);
        //事件的分发，传递是由父控件到子控件，子控件不处理在传给父控件
    }

    public void open(){
        int dx = mEditView.getMeasuredWidth()-getScrollX();
        int duration = (int) (dx/(mEditView.getMeasuredWidth()*5/6f)*mMaxDuration);
        duration = Math.max(duration, mMinDuration);
//        Log.d(TAG,"open  duration ==> " + duration);
        mScroller.startScroll(getScrollX(),0,dx,0,duration);
        isOpen = true;
        invalidate();//重新绘制
    }
    public void close(){
        int dx = -getScrollX();
        int duration = (int) (dx/(mEditView.getMeasuredWidth()*5/6f)*mMaxDuration);
        duration = Math.max(Math.abs(duration), mMinDuration);
//        Log.d(TAG,"close  duration ==> " + duration);
        mScroller.startScroll(getScrollX(),0,dx,0,duration);
        isOpen = false;
        invalidate();//重新绘制
    }

    public boolean isOpen() {
        return isOpen;
    }

    //computeScroll()方法，在滚动时调用
    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            int currX = mScroller.getCurrX();//获取当前滚动位置，差值currX逐帧递减或递增
            scrollTo(currX,0);
            invalidate();//重新绘制
        }
    }

    //重载onFinishInflate()方法，在子控件被添加到ViewGroup中时调用
    //ViewGroup中添加子控件时，会调用该方法
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        int childCount = getChildCount();
//        Log.d(TAG,"onFinishInflate  childCount ==> " + childCount);

        mContentView = getChildAt(0);

        //使用布局填充器,将布局文件(xml)转化为View对象,添加到ViewGroup中
        //attachToRoot 参数为true,表示将布局文件转化为View对象后,直接添加到ViewGroup中
        //attachToRoot 参数为false,表示将布局文件转化为View对象后,需要手动添加到ViewGroup中
        //返回当前SlideMenuViewGroup，参数是this,true
        //false,返回item_slide_action布局文件的View对象，手动添加到ViewGroup中
//        View resultView = LayoutInflater.from(getContext()).inflate(R.layout.item_slide_action,this,true);
        mEditView = LayoutInflater.from(getContext()).inflate(R.layout.item_slide_action,this,false);
        addView(mEditView);

        initEditView();

        int LayoutInflateChildCount = getChildCount();
//        Log.d(TAG,"LayoutInflateChildCount ==> " + LayoutInflateChildCount);
    }

    private void initEditView() {

        mReadTv = mEditView.findViewById(R.id.textRead);
        mTopTv = mEditView.findViewById(R.id.textTop);
        mDelTv = mEditView.findViewById(R.id.textDel);

        //设置点击事件
        mReadTv.setOnClickListener(this);
        mTopTv.setOnClickListener(this);
        mDelTv.setOnClickListener(this);

    }

    //触摸事件拦截
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //拦截事件,返回true，表示拦截事件,不传递给子控件,
        //返回false，表示不拦截事件,传递给子控件

        //判断是否横向滑动，是就拦截，否则不拦截
        final int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // 当你按下时，决定是否要拦截这个事件
                // ...
                mInterceptDownX = ev.getX();
                break;

            case MotionEvent.ACTION_MOVE:
                // 当你移动手指时，再次判断是否要拦截
                // 你可以根据手指的移动距离、速度等来决定是否拦截
                // ...
                float moveX = ev.getX();
                if (Math.abs(moveX-mInterceptDownX)>0) {
                    return true;
                }
                break;

            // 其他的动作类型...

            default:
                // 默认情况下不拦截
                return false;
        }

        // 如果决定拦截，返回 true
        // 如果不拦截或不需要判断，返回 false
        //return shouldIntercept; // shouldIntercept 是一个布尔变量，根据你的逻辑来设置
        return super.onInterceptTouchEvent(ev);
    }

    //重载onMeasure()方法，测量ViewGroup的宽高
    // 1.测量ViewGroup的宽高
    // 2.测量ViewGroup中子控件的宽高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        /*Log.d(TAG,"widthMeasureSpec:"+widthMeasureSpec);
        Log.d(TAG,"heightMeasureSpec:"+heightMeasureSpec);*/
        //wrap_content包裹内容 AT_MOST最大值
        //match_parent 父控件宽高, EXACTLY 具体值
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        /*Log.d(TAG,"width ==> " + width);
        Log.d(TAG,"height ==> " + height);*/

        //测量ViewGroup中子控件内容部分的宽高
        // LayoutParams中保存了子控件的宽高,并非测量后的宽高，而是自定义属性中的宽高，
        LayoutParams contentViewLayoutParams = mContentView.getLayoutParams();
        int contentHeight = contentViewLayoutParams.height;
        int contentWidth = contentViewLayoutParams.width;
        /*Log.d(TAG,"contentHeight ==> " + contentHeight);
        Log.d(TAG,"contentWidth ==> " + contentWidth);*/

        int childWidthSpace = 0;
        int childHeightSpace=0;
        if(contentHeight == LayoutParams.WRAP_CONTENT){//wrap_content包裹内容 -2
            childWidthSpace =MeasureSpec.makeMeasureSpec(width,MeasureSpec.AT_MOST);
            childHeightSpace =MeasureSpec.makeMeasureSpec(height,MeasureSpec.AT_MOST);
        }else if(contentHeight == LayoutParams.MATCH_PARENT){//match_parent 父控件宽高 -1
            childWidthSpace =MeasureSpec.makeMeasureSpec(width,MeasureSpec.EXACTLY);
            childHeightSpace =MeasureSpec.makeMeasureSpec(height,MeasureSpec.EXACTLY);
        }else{//已指定大小
            childWidthSpace=MeasureSpec.makeMeasureSpec(contentWidth, MeasureSpec.EXACTLY);
            childHeightSpace=MeasureSpec.makeMeasureSpec(contentHeight, MeasureSpec.EXACTLY);
        }
        /*Log.d(TAG,"childWidthSpace ==> " + childWidthSpace);
        Log.d(TAG,"childHeightSpace ==> " + childHeightSpace);*/

        // measureChild(mContentView,childWidthSpace,childHeightSpace);
        mContentView.measure(widthMeasureSpec, childHeightSpace);
        //获取内容部分测量后的宽高
        int contentMeasuredWidth = mContentView.getMeasuredWidth();
        int contentMeasuredHeight = mContentView.getMeasuredHeight();
        /*Log.d(TAG,"contentMeasuredWidth ==> " + contentMeasuredWidth);
        Log.d(TAG,"contentMeasuredHeight ==> " + contentMeasuredHeight);*/

        //测量编辑部分，宽度：3/4  高度与内容部分一样
        int editWidthSpace = MeasureSpec.makeMeasureSpec(width*3/4, MeasureSpec.EXACTLY);
//        Log.d(TAG,"editWidthSpace ==> " + editWidthSpace);
        int editHeightSpace = MeasureSpec.makeMeasureSpec(childHeightSpace, MeasureSpec.EXACTLY);
        mEditView.measure(editWidthSpace,editHeightSpace);
        int editMeasuredWidth = mEditView.getMeasuredWidth();
        int editMeasuredHeight = mEditView.getMeasuredHeight();
        /*Log.d(TAG,"editMeasuredWidth ==> " + editMeasuredWidth);
        Log.d(TAG,"editMeasuredHeight ==> " + editMeasuredHeight);*/

        //测量ViewGroup
        setMeasuredDimension(width+width*3/4,contentMeasuredHeight);
        int measuredHeight = getMeasuredHeight();
//        Log.d(TAG,"measuredHeight ==> " + measuredHeight);
        int measuredWidth = getMeasuredWidth();
//        Log.d(TAG,"measuredWidth ==> " + measuredWidth);
    }

    //重载onLayout()方法，设置ViewGroup中子控件的位置
    // 1.设置ViewGroup中子控件的位置
    //布局,布局孩子
    //l,t,r,b
    //l:左上角x坐标
    //t:左上角y坐标
    //r:右下角x坐标
    //b:右下角y坐标
    //l,t,r,b 都是相对于父控件的坐标,当前GroudView的坐标
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        Log.d(TAG,"onLayout");
        int contentLeft =0;
        int contentTop = 0;
        int contentRight = contentLeft +mContentView.getMeasuredWidth();
        int contentBottom = contentTop+mContentView.getMeasuredHeight();
        //设置内容部分的位置
        mContentView.layout(contentLeft,contentTop,contentRight,contentBottom);
        int editLeft = contentRight;
        int editTop = contentTop;
        int editRight = editLeft+mEditView.getMeasuredWidth();
        int editBottom = editTop+mEditView.getMeasuredHeight();
        //设置编辑部分的位置
        mEditView.layout(editLeft,editTop,editRight,editBottom);
    }

    public void setOnEditClickListener(OnEditClickListener listener){
        mEditClickListener = listener;
    }

    @Override
    public void onClick(View v) {
        if (mEditClickListener==null) {
            Log.d(TAG,"mEditClickListener == null");
            return;
        }
        close();
        switch (v.getId()) {
            case R.id.textRead:
                mEditClickListener.onReadClick(v);
                break;
            case R.id.textTop:
                mEditClickListener.onTopClick(v);
                break;
            case R.id.textDel:
                mEditClickListener.onDeleteClick(v);
                break;
        }



        /*if (v==mReadTv) {
            mEditClickListener.onReadClick(v);
        }else if (v==mTopTv) {
            mEditClickListener.onTopClick(v);
        }else if (v==mDelTv) {
            mEditClickListener.onDeleteClick(v);*/
        
    }

    public interface OnEditClickListener{
        void onReadClick(View v);
        void onTopClick(View v);
        void onDeleteClick(View v);
    }


}
